Amazon DynamoDB PartiQLのUPDATE文ではソートキーを省略できない
ども、ゲストのNTT東日本 大瀧です。 DynamoDBのPartiQLは、SQLに似た構文でDynamoDBのデータにクエリできる便利な仕組みです。スケーラビリティとのトレードオフとしてDynamoDBのデータ操作には様々な制約があり、ぱっと見では気づきにくいUPDATE文でのキー指定の制約について、(佐藤さんが1年半前に既にブログに書いていることなのですが)改めてハマったので書き残しておきます。
ソートキー付きでDynamoDBテーブルを作成
今回は以下のようなテーブルを用意しました。 id
がパーティションキー、 flag
がソートキーです。
SELECT文は通るのにUPDATE文はダメ
AWS管理コンソールのDynamoDB管理画面にある、PartiQLエディタからクエリを発行してみましょう。まずはSELCT文から。PartiQLにおけるSELECT文はWHERE句の条件にパーティションキーもしくはパーティションキーとソートキーをANDで入れることでDynamoDB APIのQuery APIに相当し、WHERE句なしやキー以外の属性で条件を指定すると全件取得のScan API相当になります。たとえば、パーティションキーの id
で以下のようにクエリします。
SELECT * FROM updatetest WHERE id = '48ac90be-e623-11ec-b5b3-37d2ef18d343'
クエリが通り、レコードが取得できました。
一方のUPDATE文ではパーティションキーとソートキー両方をWHERE句にANDで指定する必要があります。例えば先ほどのSELECT文とほぼ同等のクエリでは、バリデーションエラーになります。
UPDATE updatetest SET role = 'BD' WHERE id = '48ac90be-e623-11ec-b5b3-37d2ef18d343'
PartiQLのUPDATE文の更新は 単一レコードのみ 可能で複数レコードの更新ができないとのことで、レコードを特定するためにパーティションキーとソートキーの指定を要求しているわけです。アプリケーションの設計としてパーティションキーを一意にしてソートキーを自由に利用するような規約のときは、UPDATE文の発行に注意が必要です。SELECT文などであらかじめ対象レコードのソートキーの値を取得してUPDATE文を発行する対処法があるかなと思います。
また、複数レコードのUPDATEを行う場合は、複数ステートメントを許容するAPIがいくつかあるので、トランザクションの要否などで使い分けます。
ちなみに、id
パーティションキーのみのグローバルセカンダリインデックス(GSI)を張ってのUPDATE文も試してみましたが、UPDATE文はGSI指定をサポートしていませんでした。
まぁそんな気はしていましたが、一応試してみるのも大事かなと。
まとめ
Amazon DynamoDB PartiQLのUPDATE文ではソートキーを省略できない様子をご紹介しました。PartiQLはプレースホルダーを仕込みやすく個人的にはもう手離せない感じなので、制約に気を付けつつ使いこなしていきたいなと思っています。